package cn.tedu.mall.seckill.service.impl;

import cn.tedu.mall.pojo.product.vo.SkuStandardVO;
import cn.tedu.mall.pojo.seckill.model.SeckillSku;
import cn.tedu.mall.pojo.seckill.vo.SeckillSkuVO;
import cn.tedu.mall.product.service.seckill.IForSeckillSkuService;
import cn.tedu.mall.seckill.mapper.SeckillSkuMapper;
import cn.tedu.mall.seckill.service.ISeckillSkuService;
import cn.tedu.mall.seckill.utils.RedisBloomUtils;
import cn.tedu.mall.seckill.utils.SeckillCacheUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.math.RandomUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class SeckillSkuServiceImpl implements ISeckillSkuService {
    @Autowired
    private SeckillSkuMapper seckillSkuMapper;
    //具体sku的信息，还是来自于product模块
    @DubboReference
    private IForSeckillSkuService dubboSeckillSkuService;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public List<SeckillSkuVO> listSeckillSkus(Long spuId) {
        //1.根据spuId查询sku的列表
        List<SeckillSku> seckillSkus = seckillSkuMapper.selectSkusBySpuId(spuId);
        //2.声明返回值类型
        List<SeckillSkuVO> seckillSkuVOS = new ArrayList<>();
        //3.遍历seckillSkus进行转化
        for (SeckillSku seckillSku : seckillSkus) {
            //4.获取skuId，根据skuId获取key
            Long skuId = seckillSku.getSkuId();
            String seckillSkuVOKey = SeckillCacheUtils.getSeckillSkuVOKey(skuId);
            //5.声明SeckillSkuVO的对象
            SeckillSkuVO seckillSkuVO = null;
            //6.判断redis中是否存在该商品信息
            if(redisTemplate.hasKey(seckillSkuVOKey)){
                //7.缓存中有数据
                seckillSkuVO = (SeckillSkuVO) redisTemplate.boundValueOps(seckillSkuVOKey).get();
            }else{
                //8.缓存中没有数据，从数据库中查询
                SkuStandardVO skuStandardVO = dubboSeckillSkuService.getById(skuId);
                seckillSkuVO = new SeckillSkuVO();
                //9.利用BeanUtils进行同名属性赋值
                BeanUtils.copyProperties(skuStandardVO,seckillSkuVO);
                //10.赋值秒杀信息
                seckillSkuVO.setSeckillPrice(seckillSku.getSeckillPrice()); //秒杀价格
                seckillSkuVO.setSeckillLimit(seckillSku.getSeckillLimit()); //秒杀商品限购
                seckillSkuVO.setStock(seckillSku.getSeckillStock()); //秒杀商品的库存
                //11.缓存到redis中，以备后续使用
                redisTemplate.boundValueOps(seckillSkuVOKey).set(seckillSkuVO,
                        24*60*60 + RandomUtils.nextInt(100), TimeUnit.SECONDS);
            }
            //12.添加到seckillSkuVOS中
            seckillSkuVOS.add(seckillSkuVO);
        }
        //13.返回该集合
        return seckillSkuVOS;
    }
}
